﻿using System;
using System.Collections.Generic;
using System.Text;
using NUnit.Framework;
using ShootSearch.Core;
using ShootSearch.Jobs;
using ShootSearch.Spiders;
using ShootSearch.Parsers;
using ShootSearch.Util;
using System.Threading;
using System.IO;
using ShootSearch.FileSystem;
using System.Diagnostics;
using ShootSearch.Util.Serializers;
using ShootSearch.Indexers;
using Lucene.Net.Search;
using Lucene.Net.QueryParsers;
using ShootSearch.Logging;
using log4net;

namespace ShootSearch.Tests.Jobs
{
    [TestFixture]
    public class JobTests
    {
        public static void Run()
        {
            JobTests job = new JobTests();
            Log.Watch();
            //job.SetUp();
            //job.RunningTest();
            //job.ParseTest();
            //job.ListParsed();
            job.SearchTest();
        }
        
        public string path = IO.StartupPath + "\\Tasks\\BlogTest\\";

        [SetUp]
        public void SetUp()
        {
            if (log4net.Appender.FireEventAppender.Instance == null)
            {               
                throw new Exception("Log error!");
            }

            if (Directory.Exists(path))
            {
                Directory.Delete(path, true);
            }
        }

        public TaskConfig CreateBlogTaskConfig()
        {
            JobConfig cgSpider = new JobConfig(typeof(HttpSpiderJob));

            HttpSpiderJobConfig hs = cgSpider.Config as HttpSpiderJobConfig;
            hs.InitConfig.Encode = "utf-8";
            hs.InitConfig.UpdateMode = ShootSearch.Spiders.UpdateModeType.None;
            hs.InitConfig.UrlListStart.Add("http://blog.csdn.net/shootsoft/");

            UrlParserConfig upc = hs.FilterConfig.UrlParser.Config as UrlParserConfig;
            upc.EnqueueFilters.Add(new UrlFilter("^http://blog.csdn.net/shootsoft/", true));
            upc.StaticOnly = true;

            JobConfig cgParser = new JobConfig(typeof(ParserJob));

            ParserJobConfig pj = cgParser.Config as ParserJobConfig;
            pj.Parsers.Add(new AssemblyWithConfig(typeof(HtmlParser)));

            JobConfig cgIndex = new JobConfig(typeof(IndexBuilderJob));

            IndexBuilderJobConfig ibjc = cgIndex.Config as IndexBuilderJobConfig;
            LuceneIndexerConfig lic = ibjc.Indexer.Config as LuceneIndexerConfig;
            lic.InterestedAttributes.Add(new LuceneIndexerConfig.LuceneIndexerAttribute("Url",
                LuceneIndexerConfig.FieldStore.YES, LuceneIndexerConfig.FieldIndex.NO,
                LuceneIndexerConfig.FieldTermVector.NO));
            lic.InterestedAttributes.Add(new LuceneIndexerConfig.LuceneIndexerAttribute("Title",
                LuceneIndexerConfig.FieldStore.YES, LuceneIndexerConfig.FieldIndex.ANALYZED,
                LuceneIndexerConfig.FieldTermVector.YES));
            lic.InterestedAttributes.Add(new LuceneIndexerConfig.LuceneIndexerAttribute("Content",
               LuceneIndexerConfig.FieldStore.YES, LuceneIndexerConfig.FieldIndex.ANALYZED,
               LuceneIndexerConfig.FieldTermVector.YES));

            lic.InterestedAttributes.Add(new LuceneIndexerConfig.LuceneIndexerAttribute("DateTime",
               LuceneIndexerConfig.FieldStore.YES, LuceneIndexerConfig.FieldIndex.NO,
               LuceneIndexerConfig.FieldTermVector.NO));



            TaskConfig tc = new TaskConfig();
            tc.TaskName = "BlogTest";
            tc.Jobs.Add(cgSpider);
            tc.Jobs.Add(cgParser);
            tc.Jobs.Add(cgIndex);
            tc.ContextPath = path;
            return tc;
        }

        [Test]
        public void CreateTest()
        {
            TaskConfig expected = CreateBlogTaskConfig();
            expected.Save(path + Task.TAKS_CONFIG);
            TaskConfig actual = TaskConfig.Load(path + Task.TAKS_CONFIG);
            
            Assert.AreNotEqual(null,actual);
            Assert.AreEqual(expected.ContextPath, actual.ContextPath);
            Assert.AreEqual(expected.TaskName, actual.TaskName);
            Assert.AreEqual(expected.Jobs.Count, actual.Jobs.Count);
            Assert.AreEqual(expected.Jobs[0].Config.GetType().ToString(),
                actual.Jobs[0].Config.GetType().ToString());
        }

        [Test]
        public void RunningTest()
        {
            Task t = new Task();
            t.Config = CreateBlogTaskConfig();
            t.Config.Save(path + Task.TAKS_CONFIG);
            t.Start();

            while (t.Status == JobStatus.Running)
            {
                Thread.Sleep(3000);
            }            

        }

        public void ParseTest()
        {
            string dir = path + CreateBlogTaskConfig().Jobs[1].Name + "\\Output\\";
            if (Directory.Exists(dir))
            {
                Directory.Delete(dir, true);
            }
            
            
            Task t = new Task();
            t.Config = CreateBlogTaskConfig();
            t.Config.Save(path + Task.TAKS_CONFIG);
            t.Start();


            while (t.Status == JobStatus.Running)
            {
                Thread.Sleep(3000);
            }    

        }

        public void ListParsed()
        {
            string dir = path + CreateBlogTaskConfig().Jobs[1].Name + "\\Output\\";

            IFileSystem file = new STFileSystem();

            foreach (var item in file.ListAllFSIDs(dir))
            {
                Debug.WriteLine(dir + item);
                if (file.CreateOpen(dir, item))
                {
                    foreach (var fi in file.ListFileNames())
                    {
                        IFileObject obj = file.Read(fi);
                        FileObjectText fot = new FileObjectText((FileObject)obj);
                        if (fot != null)
                        {
                            Debug.WriteLine(XmlFormatter.ToXml(fot));
                        }
                        else
                        {
                            Assert.Fail("Failed to read " + fi );
                        }
                        
                    }
                }
                else
                {
                    Assert.Fail("Failed to open " + dir + item);
                }

            }
        }

        public void SearchTest()
        { 
            string dirPath = path + CreateBlogTaskConfig().Jobs[2].Name + "\\Index\\";
            Lucene.Net.Store.Directory dir = Lucene.Net.Store.FSDirectory.Open(new DirectoryInfo(dirPath));
            Lucene.Net.Search.IndexSearcher index = new Lucene.Net.Search.IndexSearcher(dir,true);
            
            QueryParser q = new QueryParser(Lucene.Net.Util.Version.LUCENE_CURRENT,"Content",
                new Lucene.Net.Analysis.Standard.StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_CURRENT));

            Query query = q.Parse("银行家");
            Hits ht = index.Search(query);

            for (int i = 0; i < ht.Length(); i++)
            {
                Console.WriteLine(ht.Doc(i).Get("Url"));
                Console.WriteLine(ht.Doc(i).Get("Title"));

            }

        }
        
    }
}
